package com.squeekeek.util.qrcode;

import java.io.File;
import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;

import com.squeekeek.util.qrcode.Core.QRAlignmentPatternFinder;
import com.squeekeek.util.qrcode.Core.QRBinarize;
import com.squeekeek.util.qrcode.Core.QRDataDecode;
import com.squeekeek.util.qrcode.Core.QRFinderPattern;
import com.squeekeek.util.qrcode.Core.QRFinderPatternFinder;
import com.squeekeek.util.qrcode.Core.QRImageCorrection;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class QRCodeTest extends Activity {
	private BaseLoaderCallback OpenCVCallbackh = new BaseLoaderCallback(this) {
		@Override
		public void onManagerConnected(int status) {
			switch(status) {
				case LoaderCallbackInterface.SUCCESS:
					Log.d("QRCode", "OpenCV Loaded Successfully!");
					break;
				default:
					super.onManagerConnected(status);
			}
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Button processBtn;
		
		super.onCreate(savedInstanceState);
		
		if(OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, OpenCVCallbackh)) {
			setContentView(R.layout.activity_qrcode_sample);
			
			processBtn = (Button) findViewById(R.id.btn_startproc);
			processBtn.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					Mat imgMat;
					Mat imgOut;
					Mat imgOutTrans;
					ImageView imgPane;
					Bitmap imgPrev;
					String imgThreshPath;
					QRAlgorithm qrCode;
					
					try {
						// Read image
						imgMat = Highgui.imread("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/test2.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE);

						// Image binarization
						imgOut = QRBinarize.ohtsu(imgMat);
						//imgOut = QRBinarize.bernsen(imgMat);
						//imgOut = QRBinarize.niblack(imgMat, -0.2);

						// Finder pattern detection
						List <Point> centerPoints = QRFinderPatternFinder.getFinderPatterns(imgOut, QRFinderPatternFinder.SCAN_ROW_MAJOR);
						List <QRFinderPattern> centerClass = QRFinderPatternFinder.getQRPoints(centerPoints);
						
						if(centerClass.size() == 0) {
							Log.d("QRCode", "Nganga.");
						}
						
						QRFinderPattern onlyOne = centerClass.get(0);
						
						// Orientation determination
						onlyOne.reorderOrientation();
						Mat rotMat = QRImageCorrection.getRotationMat(onlyOne);
						imgOutTrans = QRImageCorrection.rotateImg(imgOut, rotMat);
						onlyOne = QRImageCorrection.rotateFinderPatterns(onlyOne, rotMat);
						
						// Module width
						double modWidth = QRDataDecode.getModuleWidth(imgOutTrans, onlyOne);
						
						// Alignment pattern detection
						List <Point> alignClass = QRAlignmentPatternFinder.getAlignmentPatterns(imgOutTrans, (int) onlyOne.getPosition(QRFinderPattern.POS_UL).y, (int) onlyOne.getPosition(QRFinderPattern.POS_LL).y, (int) onlyOne.getPosition(QRFinderPattern.POS_UL).x, (int) onlyOne.getPosition(QRFinderPattern.POS_UR).x);
						
						// Perspective correction
						//Mat perspMat = QRImageCorrection.getPerspectiveMat(onlyOne, alignClass, modWidth);
						//imgOutTrans = QRImageCorrection.perspImg(imgOutTrans, perspMat);
						//onlyOne = QRImageCorrection.perspFinderPatterns(onlyOne, perspMat);
						
						for(Point iPoint : onlyOne.getArray()) {
							Core.circle(imgOutTrans, iPoint, 3, new Scalar(0x80), -1);
						}
						
						
						for(Point iAlign : alignClass) {
							Core.circle(imgOutTrans, iAlign, 3, new Scalar(0x90), -1);
						}
						
						Highgui.imwrite("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/postprocess.png", imgOutTrans);
						/*
						qrCode = new QRAlgorithm("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/test1.png");
						qrCode = new QRAlgorithm("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/test2.jpg");
						qrCode = new QRAlgorithm("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/test3.jpg");
						qrCode = new QRAlgorithm("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/test4.jpg");
						qrCode = new QRAlgorithm("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/test5.png");
						
						qrCode.localThreshBernsen();
						
						qrCode.getFinderPatterns();
						qrCode.setOrientation();
						qrCode.getVerFmtInfo();
						
						qrCode.readData();
						qrCode.decodeData();
					
						imgThreshPath = qrCode.saveThreshImg();
						*/

						imgPane = (ImageView) findViewById(R.id.frame_sampleprev);
						imgPrev = BitmapFactory.decodeFile("/storage/sdcard/Android/data/com.squeekeek.util.qrcode/files/Pictures/qrcode/postprocess.png");
						imgPane.setImageBitmap(imgPrev);
					}
					catch(Exception e) {
						Log.d("QRCode", "Exception message: " + e.getMessage());
						e.printStackTrace();
					}
				}
			});
		}
		else {
			Log.d("Main", "Cannot connect to OpenCV Manager");
		}
	}
	
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
}
